package cn.iocoder.yudao.module.jky.service.goods;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.jky.controller.admin.goodsStock.vo.GoodsSkuReqVO;
import cn.iocoder.yudao.module.jky.convert.goodsaudit.GoodsAuditConvert;
import cn.iocoder.yudao.module.jky.dal.dataobject.goodsaudit.GoodsAuditDO;
import cn.iocoder.yudao.module.jky.dal.dataobject.goodscat.GoodsCatDO;
import cn.iocoder.yudao.module.jky.dal.dataobject.goodssku.GoodsSkuDO;
import cn.iocoder.yudao.module.jky.dal.mysql.goodscat.GoodsCatMapper;
import cn.iocoder.yudao.module.jky.dal.mysql.goodssku.GoodsSkuMapper;
import cn.iocoder.yudao.module.jky.service.goodsaudit.GoodsAuditService;
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;

import cn.iocoder.yudao.module.jky.controller.admin.goods.vo.*;
import cn.iocoder.yudao.module.jky.dal.dataobject.goods.GoodsDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.jky.convert.goods.GoodsConvert;
import cn.iocoder.yudao.module.jky.dal.mysql.goods.GoodsMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.jky.enums.ErrorCodeConstants.*;

/**
 * 商品 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
@DS("slave")
public class GoodsServiceImpl implements GoodsService {

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private GoodsSkuMapper goodsSkuMapper;

    @Resource
    private GoodsCatMapper goodsCatMapper;

    @Resource
    private AdminUserApi adminUserApi;

    @Resource
    private PermissionApi permissionApi;

    @Resource
    private GoodsAuditService goodsAuditService;

    @Override
    @Transactional
    public Integer createGoods(GoodsCreateReqVO createReqVO) {

        // TODO 供应商字段和上下架字段要在这里给好
        CommonResult<AdminUserRespDTO> user = adminUserApi.getUser(SecurityFrameworkUtils.getLoginUserId());

        // 插入
        GoodsDO goods = GoodsConvert.INSTANCE.convert(createReqVO);
        // 全部是自营商城
        goods.setType(1);
        goods.setCreatetime(LocalDateTime.now());
        goods.setIsShow("N");
        if (Objects.isNull(goods.getSupplierId())) {
            goods.setSupplierId(user.getData().getDeptId().intValue());
        }
        goodsMapper.insert(goods);

        // 插入sku
        List<GoodsSkuDO> skuStockList = createReqVO.getSkuStockList();
        skuHandle(skuStockList,goods.getGoodsId());
        // 返回
        return goods.getGoodsId();
    }

    private void skuHandle(List<GoodsSkuDO> skuStockList,Integer goodsId) {
        skuStockList.forEach(sku -> {
//            List<GoodsSkuReqVO> goodsSkuReqVOS = JSONUtil.toList(sku.getSku(), GoodsSkuReqVO.class);
            sku.setSku(sku.getSpData());
            sku.setGoodsId(goodsId);
            goodsSkuMapper.insert(sku);
        });
    }

    @Override
    public void updateGoods(GoodsUpdateReqVO updateReqVO) {
        // 校验存在
        validateGoodsExists(updateReqVO.getGoodsId());

        // 必须在审核过之后才能上架
        if ("Y".equals(updateReqVO.getIsShow())) {
            GoodsAuditDO bean = goodsAuditService.getBean(updateReqVO.getGoodsId());
            if (Objects.isNull(bean)) {
                throw new ServiceException(500,"商品未审核通过！");
            }
        }

        if (CollectionUtil.isNotEmpty(updateReqVO.getSkuStockList())) {
            // 更新sku
            goodsSkuMapper.delete(new LambdaQueryWrapperX<GoodsSkuDO>().eq(GoodsSkuDO::getGoodsId, updateReqVO.getGoodsId()));

            List<GoodsSkuDO> skuStockList = updateReqVO.getSkuStockList();
            skuStockList.forEach(item -> {
                item.setGoodsId(updateReqVO.getGoodsId());
                item.setSku(item.getSpData());
            });
            goodsSkuMapper.insertBatch(skuStockList);
        }


        // 更新
        GoodsDO updateObj = GoodsConvert.INSTANCE.convert(updateReqVO);
        goodsMapper.updateById(updateObj);
    }

    @Override
    public void deleteGoods(Integer id) {
        // 校验存在
        validateGoodsExists(id);
        // 删除
        goodsMapper.deleteById(id);
    }

    private void validateGoodsExists(Integer id) {
        if (goodsMapper.selectById(id) == null) {
            throw exception(GOODS_NOT_EXISTS);
        }
    }

    @Override
    public GoodsDO getGoods(Integer id) {
        return goodsMapper.selectById(id);
    }

    @Override
    public List<GoodsDO> getGoodsList(Collection<Integer> ids) {
        return goodsMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<GoodsDO> getGoodsPage(GoodsPageReqVO pageReqVO) {


        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        assert loginUser != null;

        // 如果是供应商管理员角色,获取供应商租户的所有供应商的商品
        if (loginUser.getId() == 110) {
            PageResult<GoodsDO> goodsDOPageResult = goodsMapper.selectPage(pageReqVO);
            goodsDOPageResult.getList().forEach(item -> {
                GoodsCatDO goodsCatDO = goodsCatMapper.selectById(item.getCatId());
                item.setCatName(goodsCatDO.getCatName());
            });
            return goodsAuditService.goodsAudit(goodsDOPageResult);

        }

        // 供应商用户只能获取它自己的商品
        CommonResult<AdminUserRespDTO> user = adminUserApi.getUser(loginUser.getId());
        if (Objects.nonNull(user.getData())) {
            CommonResult<Boolean> supplier = permissionApi.hasAnyRoles(loginUser.getId(), "supplier");
            if (supplier.getData()) {
                pageReqVO.setSupplierId(user.getData().getDeptId().intValue());
                PageResult<GoodsDO> goodsDOPageResult = goodsMapper.selectPage(pageReqVO);
                return goodsAuditService.goodsAudit(goodsDOPageResult);
            }
        }

        PageResult<GoodsDO> goodsDOPageResult = goodsAuditService.goodsAudit(goodsMapper.selectPage(pageReqVO));
        goodsDOPageResult.getList().forEach(item -> {
            GoodsCatDO goodsCatDO = goodsCatMapper.selectById(item.getCatId());
            item.setCatName(goodsCatDO.getCatName());
        });
        return goodsDOPageResult;
    }

    @Override
    public void auditGoods(GoodsAuditReqVO reqVO) {
        GoodsAuditDO goodsAuditDO = GoodsAuditConvert.INSTANCE.convert(reqVO);
        goodsAuditService.createGoodsAudit(goodsAuditDO);
    }

    @Override
    public List<GoodsDO> getGoodsList(GoodsExportReqVO exportReqVO) {
        return goodsMapper.selectList(exportReqVO);
    }

    @Override
    public void updateGoodsCatState(GoodsUpdateStateReqVO updateStateReqVO) {
        // 校验存在
        validateGoodsExists(updateStateReqVO.getGoodsId());
        // 必须在审核过之后才能上架
        if ("Y".equals(updateStateReqVO.getIsShow())) {
            GoodsAuditDO bean = goodsAuditService.getBean(updateStateReqVO.getGoodsId());
            if (Objects.isNull(bean)) {
                throw new ServiceException(500,"商品未审核通过！");
            }
        }
        // 更新
        GoodsDO updateObj = GoodsConvert.INSTANCE.convert(updateStateReqVO);
        goodsMapper.updateById(updateObj);
    }

    @Override
    public List<GoodsSkuDO> getSkuList(Integer id) {
        List<GoodsSkuDO> goodsSkuDOS = goodsSkuMapper.selectList(new LambdaQueryWrapperX<GoodsSkuDO>().eq(GoodsSkuDO::getGoodsId, id));
        goodsSkuDOS.forEach(item -> {
            item.setSpData(item.getSku());
        });
        return goodsSkuDOS;
    }

}
